local upload = require "resty.upload"
local json = require "cjson"
local redis = require("resty.redis")

local tevitalk_redis = redis:new()   
tevitalk_redis:set_timeout(1000)  
local ok, err = tevitalk_redis:connect("128.14.157.130", 6379, 0)  
if not ok then  
    ngx.log(ngx.ERR, "connect to redis error : ", err)  
end
local res, err = tevitalk_redis:auth("amigo123")
if not res then
    ngx.log(ngx.ERR, "failed to authenticate: ", err)
end  

local companion_redis = redis:new()   
companion_redis:set_timeout(1000)  
local ok, err = companion_redis:connect("10.12.104.30", 6379, 0)  
if not ok then  
    ngx.log(ngx.ERR, "connect to redis error : ", err)  
end
local res, err = companion_redis:auth("amigo123")
if not res then
    ngx.log(ngx.ERR, "failed to authenticate: ", err)
end 


function setResponse(code, success, msg, data)
    return {
       meta = {
            code = code,
            success = success,
            msg = msg
        },
        data = data
    }
end

local root_path = "/data/resource"
local user_id = ""
--获取请求头table
local headers_tab = ngx.req.get_headers()
if headers_tab then
    local access_token = headers_tab["access_token"] 
    if access_token == nil then
        access_token = headers_tab["ACCESS_TOKEN"]
    end
    ngx.log(ngx.INFO, "access_token: " .. (access_token and access_token or ""))
    if access_token then
        -- ngx.log(ngx.INFO, "进入了access_token")
        if string.find(access_token ,"COMPANION") then
            --companion项目
            root_path = "/data/resource/compaion"
            local res, err = companion_redis:get("token:" .. access_token)
            if res ~= ngx.null then
                -- ngx.log(ngx.INFO, "redis查询返回值 " .. res)
                local json_table = json.decode(res);
                user_id = json_table["userId"]
            end
            local ok, err = companion_redis:set_keepalive(pool_max_idle_time, pool_size)  
            if not ok then  
                ngx.log(ngx.NOTICE, "set keepalive error : ", err)  
            end  
        else
            --tevitalk项目
            local res, err = tevitalk_redis:get(access_token)
            if res ~= ngx.null then
                 -- ngx.log(ngx.INFO, "redis查询返回值 " .. res)
                 local json_table = json.decode(res);
                 user_id = json_table["user"]["id"]               
            end
            local ok, err = tevitalk_redis:set_keepalive(pool_max_idle_time, pool_size)  
            if not ok then  
                ngx.log(ngx.NOTICE, "set keepalive error : ", err)  
            end

        end
    end
end
ngx.log(ngx.INFO, "user_id: " .. user_id)
if user_id == "" and access_token~="tevitalk" then
    ngx.log(ngx.INFO, "没有登录")
    ngx.say(json.encode(setResponse(401, false, "未登录", "")))
    return

end

local chunk_size = 8192 -- should be set to 4096 or 8192
                     -- for real-world settings

function get_filename(res)  
    local filename = ngx.re.match(res,'(.+)filename="(.+)"(.*)')  
    if filename then   
        return filename[2]  
    end  
end 

function get_file_ext(res)
    local file_name = get_filename(res)
    if not file_name then
        return ""
    end
     return file_name:match(".+%.(%w+)$")
end



function random(n, m)
    math.randomseed(os.clock()*math.random(1000000,90000000)+math.random(1000000,90000000))
    return math.random(n, m)
end
 
function randomNumber(len)
    local rt = ""
    for i=1,len,1 do
        if i == 1 then
            rt = rt..random(1,9)
        else
            rt = rt..random(0,9)
        end
    end
    return rt
end
 
function randomLetter(len)
    local rt = ""
    for i = 1, len, 1 do
        rt = rt..string.char(random(97,122))
    end
    return rt
end



--下面的代码段校验，目录是否存在，不存在则创建，这里是按照 "年/月/日" 字符串创建文件夹
local time = os.time();
local os_data = os.date("%Y/%m/%d",time)
local new_path = root_path .. os_data   

local dfile = io.open(new_path, "r")
if not dfile then 
    ngx.log(ngx.INFO, "dfile -- " .. new_path) -- /data/images/images/2019/03/22
    local md = "mkdir -p "
    local mdpath = md .. new_path
    os.execute(mdpath)
else
    dfile:close()
end
--到这里，校验结束


local form, err = upload:new(chunk_size)
if not form then
    ngx.log(ngx.ERR, "failed to new upload: ", err)
    ngx.exit(500)
end

form:set_timeout(100000) -- 100 sec

local file_name = ""
local file = nil
local my_error = nil
local mysql_file_name_table = {} --数据库存储的路径地址

while true do
    local typ, res, err = form:read()
    if not typ then
        ngx.log(ngx.ERR, "failed to read: ", err)
        ngx.say (json.encode(setResponse(200, true, "请求成功", "")))
        return
    end

    if typ == "header" then
        if res[1] ~= "Content-Type" then
            file_name = get_filename(res[2])
            if file_name then
                --local file_path = "/data/images/images/" ..file_name
                local new_file_name = "group1" .. user_id .. os.date("%Y%m%d%H%M%S" .. randomNumber(3), time)
                local file_ext = get_file_ext(res[2])
                local file_path = ""
                if file_ext == nil then
                    table.insert(mysql_file_name_table, os_data .. "/" .. new_file_name)
                    file_path = new_path .. "/" .. new_file_name
                else
                    table.insert(mysql_file_name_table, os_data .. "/" .. new_file_name .. "." .. file_ext)
                    file_path = new_path .. "/" .. new_file_name .. "." .. file_ext
                end
                ngx.log(ngx.INFO, "file_path: " .. file_path) --  /data/images/images/2019/03/22/3437020190322143204996.png
                file, my_error= io.open(file_path, "w+")
                if not file then
                    ngx.log(ngx.ERR, "failed to open file ", json.encode(my_error))
                    return
                end
            end
        end
    elseif typ == "body" then
        file:write(res)
    elseif typ == "part_end" then
        
        if file then
            file:close()
            file = nil
        end  

    elseif typ =="eof" then
        break;
    end
end
-- ngx.log(ngx.INFO, "最终文件路径: " .. json.encode(mysql_file_name_table))
ngx.say (json.encode(setResponse(200, true, "请求成功", mysql_file_name_table)))
ngx.log(ngx.INFO, "upload success!!!")
